package com.ms.oschina.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import android.widget.Toast;

public class PhotoUtilChange {

	/**
	 * 因为处理不同
	 * 
	 * @param takePhotoCode
	 *            Uri originalUri = data.getData();
	 *            image=ImageUtil.getBitmapFromUrl(originalUri.toString());
	 ********************************************************************************** 
	 * @param pickPhotoCode
	 *            Bundle extras = data.getExtras(); image = (Bitmap)
	 *            extras.get("data");
	 * @param tempFile
	 *            拍照时的临时文件 需要zoom时
	 * **/
	public static boolean getPhotoDialog(final Activity activity,
			final int takePhotoCode, final int pickPhotoCode,
			final File tempFile) {
		final CharSequence[] items = { "相册", "拍照" };
		AlertDialog dlg = new AlertDialog.Builder(activity).setTitle("选择图片")
				.setItems(items, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int item) {
						if (item == 1) {
							Intent getImageByCamera = new Intent(
									"android.media.action.IMAGE_CAPTURE");
							getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT,
									Uri.fromFile(tempFile));
							activity.startActivityForResult(getImageByCamera,
									takePhotoCode);
						} else {
							Intent getImage = new Intent(
									Intent.ACTION_GET_CONTENT);
							getImage.addCategory(Intent.CATEGORY_OPENABLE);
							getImage.setType("image/jpeg");
							activity.startActivityForResult(getImage,
									pickPhotoCode);
						}
					}
				}).create();
		dlg.show();
		return true;
	}

	/**
	 * 拍照
	 * 
	 * @param activity
	 * @param takePhotoCode
	 * @param tempFile
	 * @return
	 */
	public static boolean takePhoto(Activity activity, int takePhotoCode,
			File tempFile) {
		if (!tempFile.exists()) {
			tempFile.mkdir();// 手机禁止了系统公共的默认路径的访问。所以为了兼容所有的手机，推荐将要保存的文件保存到自定义的文件夹下。
		}

		Intent getImageByCamera = new Intent(
				"android.media.action.IMAGE_CAPTURE");
		getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT,
				Uri.fromFile(tempFile));
		activity.startActivityForResult(getImageByCamera, takePhotoCode);
		return true;
	}

	public static boolean pickPhoto(Activity activity, int imageCode,
			File tempFile) {
		Intent getImage = new Intent(Intent.ACTION_GET_CONTENT);
		// getImage.setAction(Intent.ACTION_PICK);//Pick an item fromthe data
		getImage.addCategory(Intent.CATEGORY_OPENABLE);
		getImage.setType("image/*");
		activity.startActivityForResult(getImage, imageCode);
		return true;
	}

	/**
	 * 拍照获取图片的方式 用于切割的图片大小被限制在500,500
	 * 
	 * @param context
	 * @param zoomCode
	 * @param temppath
	 *            拍照前生成的临时路劲
	 * @return 新的路劲
	 */
	public static String onPhotoFromCamera(final Activity context,
			final int zoomCode, final String temppath, final int aspectX,
			final int aspectY) {
		try {
			Bitmap btp = getLocalImage(new File(temppath), 1000, 1000);
			compressImage(btp, new File(temppath + "temp.jpg"), 30);
			photoZoom(context, Uri.fromFile(new File(temppath + "temp.jpg")),
					Uri.fromFile(new File(temppath)), zoomCode, aspectX,
					aspectY);
		} catch (Exception e) {
			Toast.makeText(context, "图片加载失败", 1000).show();
		}

		return temppath;
	}

	/**
	 * 图片切割完调用 如果还需要 Bitmap 调用getLocalImage
	 * 
	 * @param path
	 * @param rw
	 * @param rh
	 * @param compress
	 * @return
	 */
	public static File onPhotoZoom(String path, int rw, int rh, int compress) {

		File f = new File(path);
		Bitmap btp = PhotoUtilChange.getLocalImage(f, rw, rh);
		compressImage(btp, f, compress);
		return f;
	}

	/**
	 * 相册获取图片,用于切割的图片大小被限制在500,500 aspectX aspectY 是宽高的比例
	 * 
	 * @param context
	 * @param zoomCode
	 * @param temppath
	 *            希望生成的路劲
	 * @param data
	 * 
	 */
	public static void onPhotoFromPick(final Activity context,
			final int zoomCode, final String temppath, final Intent data,
			final int aspectX, final int aspectY) {
		try {
			Bitmap btp = checkImage(context, data);
			compressImage(btp, new File(temppath + "temp.jpg"), 30);
			PhotoUtilChange.photoZoom(context,
					Uri.fromFile(new File(temppath + "temp.jpg")),
					Uri.fromFile(new File(temppath)), zoomCode, aspectX,
					aspectY);
		} catch (Exception e) {
			Toast.makeText(context, "图片加载失败", 1000).show();
		}
	}

	/**
	 * data 中检出图片
	 * 
	 * @param activity
	 * @param data
	 * @return
	 */
	public static Bitmap checkImage(Activity activity, Intent data) {
		Bitmap bitmap = null;
		try {
			Uri originalUri = data.getData();
			String path = getPath(originalUri, activity);
			File f = activity.getExternalCacheDir();
			String pp = f.getAbsolutePath();
			if (path.indexOf(pp) != -1) {
				path = path.substring(path.indexOf(pp), path.length());
			}
			bitmap = getLocalImage(new File(path), 1000, 1000);
		} catch (Exception e) {
		} finally {
			return bitmap;
		}
	}

	/**
	 * 图片压缩 上传图片时建议compress为30
	 * 
	 * @param bm
	 * @param f
	 */
	public static void compressImage(Bitmap bm, File f, int compress) {
		if (bm == null)
			return;
		File file = f;
		try {
			if (file.exists()) {
				file.delete();
			}
			file.createNewFile();
			OutputStream outStream = new FileOutputStream(file);
			bm.compress(android.graphics.Bitmap.CompressFormat.JPEG, compress,
					outStream);
			outStream.flush();
			outStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 由本地文件获取希望大小的文件
	 * 
	 * @param f
	 * @return
	 */
	public static Bitmap getLocalImage(File f, int swidth, int sheight) {
		File file = f;
		if (file.exists()) {
			try {
				file.setLastModified(System.currentTimeMillis());
				FileInputStream in = new FileInputStream(file);

				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inJustDecodeBounds = true;
				BitmapFactory.decodeStream(in, null, options);
				int sWidth = swidth;
				int sHeight = sheight;
				int mWidth = options.outWidth;
				int mHeight = options.outHeight;
				int s = 1;
				while ((mWidth / s > sWidth * 2) || (mHeight / s > sHeight * 2)) {
					s *= 2;
				}
				options = new BitmapFactory.Options();
				options.inSampleSize = s;
				options.inPreferredConfig = Bitmap.Config.RGB_565;
				options.inPurgeable = true;
				options.inInputShareable = true;
				try {
					// 4. inNativeAlloc 属性设置为true，可以不把使用的内存算到VM里
					BitmapFactory.Options.class.getField("inNativeAlloc")
							.setBoolean(options, true);
				} catch (Exception e) {
				}
				in.close();
				// 再次获取
				in = new FileInputStream(file);
				Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
				in.close();
				return bitmap;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} catch (Error e) {
				System.gc();
				return null;
			}
		}
		return null;
	}

	/**
	 * aspectY Y对于X的比例 outputX X 的宽
	 * **/
	public static void photoZoom(Activity activity, Uri uri, Uri outUri,
			int photoResoultCode, int aspectX, int aspectY) {
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		intent.putExtra("crop", "true");
		// aspectX aspectY 是宽高的比例
		if (aspectY > 0) {
			intent.putExtra("aspectX", aspectX);
			intent.putExtra("aspectY", aspectY);
		}
		intent.putExtra("scale", aspectX == aspectY);
		intent.putExtra("return-data", true);
		intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
		intent.putExtra(MediaStore.EXTRA_OUTPUT, outUri);
		intent.putExtra("noFaceDetection", true); //
		activity.startActivityForResult(intent, photoResoultCode);
	}

	/**
	 * 保存zoom之后的图片 zoom: 缩放
	 * 
	 * @param data
	 *            zoom后的intent
	 * @param context
	 *            上下文
	 * @return
	 */
	public static Bitmap getZoomBitMap(Intent data, Context context) {
		try {
			Bundle extras = data.getExtras();
			if (extras != null) {
				Bitmap bitmap = extras.getParcelable("data");
				return bitmap;
			}
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(context, "出现未知异常,请尝试其他图片", Toast.LENGTH_SHORT)
					.show();
		}
		return null;
	}

	/**
	 * 根据指定的图像路径和大小来获取缩略图 此方法有两点好处： 1.
	 * 使用较小的内存空间，第一次获取的bitmap实际上为null，只是为了读取宽度和高度，
	 * 第二次读取的bitmap是根据比例压缩过的图像，第三次读取的bitmap是所要的缩略图。 2.
	 * 缩略图对于原图像来讲没有拉伸，这里使用了2.2版本的新工具ThumbnailUtils，使 用这个工具生成的图像不会被拉伸。
	 * 
	 * @param imagePath
	 *            图像的路径
	 * @param width
	 *            指定输出图像的宽度 单位像素
	 * @param height
	 *            指定输出图像的高度
	 * @return 生成的缩略图
	 */
	public static Bitmap getImageThumbnail(String imagePath, int width,
			int height) {
		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		// 获取这个图片的宽和高，注意此处的bitmap为null
		bitmap = BitmapFactory.decodeFile(imagePath, options);
		options.inJustDecodeBounds = false; // 设为 false
		// 计算缩放比
		int h = options.outHeight;
		int w = options.outWidth;
		int beWidth = w / width;
		int beHeight = h / height;
		int be = 1;
		if (beWidth < beHeight) {
			be = beWidth;
		} else {
			be = beHeight;
		}
		if (be <= 0) {
			be = 1;
		}
		options.inSampleSize = be;
		// 重新读入图片，读取缩放后的bitmap，注意这次要把options.inJustDecodeBounds 设为 false
		bitmap = BitmapFactory.decodeFile(imagePath, options);
		// 利用ThumbnailUtils来创建缩略图，这里要指定要缩放哪个Bitmap对象
		bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
				ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
		return bitmap;
	}

	/**
	 * 根据系统相册选择的文件获取路径
	 * 
	 * @param uri
	 */
	@SuppressLint("NewApi")
	public static String getPath(Uri uri, Activity activity) {
		int sdkVersion = Build.VERSION.SDK_INT;
		// 高于4.4.2的版本
		if (sdkVersion >= 19) {
			Log.e("zoubo", "uri auth: " + uri.getAuthority());
			if (isExternalStorageDocument(uri)) {
				String docId = DocumentsContract.getDocumentId(uri);
				String[] split = docId.split(":");
				String type = split[0];
				if ("primary".equalsIgnoreCase(type)) {
					return Environment.getExternalStorageDirectory() + "/"
							+ split[1];
				}
			} else if (isDownloadsDocument(uri)) {
				final String id = DocumentsContract.getDocumentId(uri);
				final Uri contentUri = ContentUris.withAppendedId(
						Uri.parse("content://downloads/public_downloads"),
						Long.valueOf(id));
				return getDataColumn(UiUtils.getContext(), contentUri, null,
						null);
			} else if (isMediaDocument(uri)) {
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				Uri contentUri = null;
				if ("image".equals(type)) {
					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
				} else if ("video".equals(type)) {
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
				} else if ("audio".equals(type)) {
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
				}
				final String selection = "_id=?";
				final String[] selectionArgs = new String[] { split[1] };
				return getDataColumn(UiUtils.getContext(), contentUri,
						selection, selectionArgs);
			} else if (isMedia(uri)) {
				String[] proj = { MediaStore.Images.Media.DATA };
				Cursor actualimagecursor = activity.managedQuery(uri, proj,
						null, null, null);
				int actual_image_column_index = actualimagecursor
						.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
				actualimagecursor.moveToFirst();
				return actualimagecursor.getString(actual_image_column_index);
			}
		} else if ("content".equalsIgnoreCase(uri.getScheme())) {
			// Return the remote address
			if (isGooglePhotosUri(uri))
				return uri.getLastPathSegment();
			return getDataColumn(UiUtils.getContext(), uri, null, null);
		}
		// File
		else if ("file".equalsIgnoreCase(uri.getScheme())) {
			return uri.getPath();
		}
		return null;
	}

	/**
	 * uri路径查询字段
	 * 
	 * @param context
	 * @param uri
	 * @param selection
	 * @param selectionArgs
	 * @return
	 */
	public static String getDataColumn(Context context, Uri uri,
			String selection, String[] selectionArgs) {
		Cursor cursor = null;
		final String column = "_data";
		final String[] projection = { column };
		try {
			cursor = context.getContentResolver().query(uri, projection,
					selection, selectionArgs, null);
			if (cursor != null && cursor.moveToFirst()) {
				final int index = cursor.getColumnIndexOrThrow(column);
				return cursor.getString(index);
			}
		} finally {
			if (cursor != null)
				cursor.close();
		}
		return null;
	}

	private static boolean isExternalStorageDocument(Uri uri) {
		return "com.android.externalstorage.documents".equals(uri
				.getAuthority());
	}

	public static boolean isDownloadsDocument(Uri uri) {
		return "com.android.providers.downloads.documents".equals(uri
				.getAuthority());
	}

	public static boolean isMediaDocument(Uri uri) {
		return "com.android.providers.media.documents".equals(uri
				.getAuthority());
	}

	public static boolean isMedia(Uri uri) {
		return "media".equals(uri.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is Google Photos.
	 */
	public static boolean isGooglePhotosUri(Uri uri) {
		return "com.google.android.apps.photos.content".equals(uri
				.getAuthority());
	}
}
